package com.netrust.cmsx.utils.bean;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class BeanUtils extends org.apache.commons.beanutils.BeanUtils{
	 public static void beanCopy(Object source, Object target) {
		 
	        if (null == source || null == target) {
	            return ;
	        }
	 
	 
	        Class<?> sourceClazz = source.getClass();
	        Class<?> targetClazz = target.getClass();
	        Field[] fields = targetClazz.getDeclaredFields(); // 取到所有类下的属性，也就是变量名
	        Field field;
	 
	        for (int i = 0; i < fields.length; i++) {
	            field = fields[i];
	            String fieldName = field.getName();
	            // 把属性的第一个字母处理成大写
	            String stringLetter = fieldName.substring(0, 1).toUpperCase();
	            // 取得setter方法名，比如setBbzt
	            String setName = "set" + stringLetter + fieldName.substring(1);
	            // 取得getter方法名
	            String getName = "get" + stringLetter + fieldName.substring(1);
	            // 真正取得get方法。
	            Method setMethod = null;
	            // 真正取得set方法
	            Method sourceGetMethod = null;
	 
	            Class<?> fieldClass = field.getType();
	            try {
	                if (isHaveSuchMethod(targetClazz, setName)) {
	                    setMethod = targetClazz.getMethod(setName, fieldClass);
	                    if (isHaveSuchMethod(sourceClazz, getName)) {
	                        sourceGetMethod = sourceClazz.getMethod(getName);
	                    }
	                    Object sourceValue = sourceGetMethod.invoke(source);
	                    if (null != sourceValue) {
	                        setMethod.invoke(target, sourceValue);// 为其赋值
	                    }
	                }
	            } catch (Exception e) {
	                 
	            }
	 
	        }
	        return ;
	    }
	     
	     
	    /**
	     * 将来源对象的值 ，赋给目标对象</br>
	     * @param source    来源对象
	     * @param target    目标对象
	     * @param isCopyNull    如果source中的值为null时，是否将其赋给target对象
	     */
	    public static void beanCopy(Object source, Object target, boolean isCopyNull) {
	 
	        if (null == source || null == target) {
	            return ;
	        }
	 
	 
	        Class<?> sourceClazz = source.getClass();
	        Class<?> targetClazz = target.getClass();
	        Field[] fields = targetClazz.getDeclaredFields(); // 取到所有类下的属性，也就是变量名
	        Field field;
	 
	        for (int i = 0; i < fields.length; i++) {
	            field = fields[i];
	            String fieldName = field.getName();
	            // 把属性的第一个字母处理成大写
	            String stringLetter = fieldName.substring(0, 1).toUpperCase();
	            // 取得setter方法名，比如setBbzt
	            String setName = "set" + stringLetter + fieldName.substring(1);
	            // 取得getter方法名
	            String getName = "get" + stringLetter + fieldName.substring(1);
	            // 真正取得get方法。
	            Method setMethod = null;
	            // 真正取得set方法
	            Method sourceGetMethod = null;
	 
	            Class<?> fieldClass = field.getType();
	            try {
	                if (isHaveSuchMethod(targetClazz, setName)) {
	                    setMethod = targetClazz.getMethod(setName, fieldClass);
	                    if (isHaveSuchMethod(sourceClazz, getName)) {
	                        sourceGetMethod = sourceClazz.getMethod(getName);
	                    }
	                    Object sourceValue = sourceGetMethod.invoke(source);
	                    if (null != sourceValue) {
	                        setMethod.invoke(target, sourceValue);// 为其赋值
	                    }else{
	                        if(isCopyNull){
	                            setMethod.invoke(target, sourceValue);
	                        }
	                    }
	                }
	            } catch (Exception e) {
	             
	            }
	        }
	        return ;
	    }
	    
	    /**
	     * 把Map<String,Object>处理成实体类
	     * @param clazz     想要的实体类
	     * @param list      包含信息的列表
	     * @return
	     */
	    public static <T> List<T> mapToList(Class<T> clazz, List<Map<String,Object>> list){
	         
	        if(null == list || list.size() == 0){
	            return null;
	        }
	        List<T> result = new ArrayList<T>();
	        Map<String,Object> map;
	        for(Iterator<Map<String,Object>> iter = list.iterator(); iter.hasNext();){
	            map = iter.next();
	            result.add(mapToObject(clazz, map));
	        }
	        return result;
	    }
	     
	    /**
	     * 把Map<String,Object>处理成实体类
	     * @param clazz     想要的实体类
	     * @param map       包含信息的Map对象
	     * @return
	     */
	    public static <T> T mapToObject(Class<T> clazz, Map<String,Object> map){
	         
	        if(null == map){
	            return null;
	        }
	         
	        Field[] fields = clazz.getDeclaredFields(); //取到所有类下的属性，也就是变量名
	        Field field;
	        T o = null;
	        try {
	            o = clazz.newInstance();
	        } catch (InstantiationException e1) {
	            e1.printStackTrace();
	        } catch (IllegalAccessException e1) {
	            e1.printStackTrace();
	        }
	        for(int i=0; i<fields.length; i++){
	            field = fields[i];
	            String fieldName = field.getName();
	            //把属性的第一个字母处理成大写
	            String stringLetter=fieldName.substring(0, 1).toUpperCase();    
	            //取得set方法名，比如setBbzt
	            String setName="set"+stringLetter+fieldName.substring(1);    
	            //真正取得get方法。
	            Method setMethod = null;
	            Class<?> fieldClass = field.getType();
	            try {
	                Object value = map.get(fieldName);
	                if (value != null && String.valueOf(value).trim().length() > 0 && isHaveSuchMethod(clazz, setName)) {
	                    if (fieldClass == String.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        setMethod.invoke(o, String.valueOf(value));// 为其赋值
	                    } else if (fieldClass == Integer.class || fieldClass == int.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        setMethod.invoke(o,
	                                Integer.parseInt(String.valueOf(value)));// 为其赋值
	                    } else if (fieldClass == Boolean.class || fieldClass == boolean.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        setMethod.invoke(o,
	                                Boolean.getBoolean(String.valueOf(value)));// 为其赋值
	                    } else if (fieldClass == Short.class || fieldClass == short.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        setMethod.invoke(o,
	                                Short.parseShort(String.valueOf(value)));// 为其赋值
	                    } else if (fieldClass == Long.class || fieldClass == long.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        setMethod.invoke(o,
	                                Long.parseLong(String.valueOf(value)));// 为其赋值
	                    } else if (fieldClass == Double.class || fieldClass == double.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        setMethod.invoke(o,
	                                Double.parseDouble(String.valueOf(value)));// 为其赋值
	                    } else if (fieldClass == Float.class || fieldClass == float.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        setMethod.invoke(o,
	                                Float.parseFloat(String.valueOf(value)));// 为其赋值
	                    } else if (fieldClass == BigInteger.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        setMethod.invoke(o, BigInteger.valueOf(Long
	                                .parseLong(String.valueOf(value))));// 为其赋值
	                    } else if (fieldClass == BigDecimal.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        setMethod.invoke(o, BigDecimal.valueOf(Double
	                                .parseDouble(String.valueOf(value))));// 为其赋值
	                    } else if (fieldClass == Date.class) {
	                        setMethod = clazz.getMethod(setName, fieldClass);
	                        if (map.get(fieldName).getClass() == java.sql.Date.class) {
	                            setMethod.invoke(o, new Date(
	                                    ((java.sql.Date) value).getTime()));// 为其赋值
	                        } else if (map.get(fieldName).getClass() == java.sql.Time.class) {
	                            setMethod.invoke(o, new Date(
	                                    ((java.sql.Time) value).getTime()));// 为其赋值
	                        } else if (map.get(fieldName).getClass() == java.sql.Timestamp.class) {
	                            setMethod.invoke(o, new Date(
	                                    ((java.sql.Timestamp) value).getTime()));// 为其赋值
	                        }
	                    } else if(fieldClass == List.class){
	                         
	                    }
	                }
	            } catch (Exception e) {
	            }
	             
	        }
	        return o;
	    }
	  
	    /**
	     * 判断某个类里是否有某个方法
	     * @param clazz
	     * @param methodName
	     * @return
	     */
	    public static boolean isHaveSuchMethod(Class<?> clazz, String methodName){
	        Method[] methodArray = clazz.getMethods();
	        boolean result = false;
	        if(null != methodArray){
	            for(int i=0; i<methodArray.length; i++){
	                if(methodArray[i].getName().equals(methodName)){
	                    result = true;
	                    break;
	                }
	            }
	        }
	        return result;
	    }
	    
}
